package com.zhihaoliang.coroutine.buss.flow.func

import com.zhihaoliang.coroutine.util.log
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*

/**
 * @author 支豪亮
 * @date 2022/10/27 11:39
 * @des Flow cancellation checks
 */
object FlowCancel {
    /**
     * 因为 繁忙的数据流无法取消
     */
    fun onAsFlow(mainScope: CoroutineScope) = mainScope.launch {
        (1..5).asFlow().collect { value ->
            if (value == 3) cancel()
            log("asFlow : $value")
        }
    }

    /**
     * 因为 asFlow 默认使用 ensureActive检查所以可以取消
     */
    fun onFlow(mainScope: CoroutineScope) = mainScope.launch {
        foo().collect { value ->
            if (value == 3) cancel()
            log("cancel : $value")
        }
    }

    /**
     * 通过 cancellable 是流可以被取消
     */
    fun onCancel(mainScope: CoroutineScope) = mainScope.launch {
        (1..5).asFlow().cancellable().collect { value ->
            if (value == 3) cancel()
            log("asFlow : $value")
        }
    }

    /**
     * 通过 currentCoroutineContext().ensureActive() 是流可以被取消
     */
    fun onEnsureActive(mainScope: CoroutineScope) = mainScope.launch {
        (1..5).asFlow().onEach { currentCoroutineContext().ensureActive() }.collect { value ->
            if (value == 3) cancel()
            log("asFlow : $value")
        }
    }

    private fun foo(): Flow<Int> = flow {
        for (i in 1..5) {
            log("Emitting $i")
            emit(i)
        }
    }


}